package com.wutianyi.controller.innvo;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.wutianyi.module.commons.Item;
import com.wutianyi.module.commons.Pair;
import com.wutianyi.module.commons.PropertyGroup;
import com.wutianyi.module.commons.PropertyGroupType;
import com.wutianyi.module.commons.config.ConfigDO;
import com.wutianyi.module.commons.config.ConfigTypeEnum;
import com.wutianyi.module.company.Company;
import com.wutianyi.module.member.dataobject.MemberDO;
import com.wutianyi.module.services.CompanyServices;
import com.wutianyi.module.services.ConfigServices;
import com.wutianyi.module.services.MemberServices;
import com.wutianyi.service.SecurityManager;
import com.wutianyi.utils.MyStringUtils;

@Controller
public class CompanyInfoController {

	private String viewName = "innov/company_info";

	@Autowired
	private CompanyServices companyServices;

	@Autowired
	private ConfigServices configServices;

	@Autowired
	private SecurityManager securityManager;

	@Autowired
	private MemberServices memberServices;

	@RequestMapping(value = "/innov/company_info.do")
	public ModelAndView execute(@ModelAttribute("member") MemberDO member) {

		String viewName = this.viewName;

		ModelAndView modelAndView = new ModelAndView();
		Company company = companyServices
				.getCompanyByCId(member.getCompanyId());

		if (null == company) {
			viewName = "404";
		}
		modelAndView.setViewName(viewName);
		modelAndView.addObject("company", company);

		Set<Integer> configIds = company.getConfigIds();

		List<ConfigDO> configDOs = new ArrayList<ConfigDO>();

		List<ConfigDO> standardConfigs = configServices
				.listConfigsByType(ConfigTypeEnum.COMPANY_STANDARD_PROPERTIES);

		StringBuilder builder = new StringBuilder();
		StringBuilder companyPgIds = new StringBuilder();
		for (ConfigDO config : standardConfigs) {
			if (!configIds.contains(config.getId())) {
				builder.append(config.getId());
				builder.append(',');
				configDOs.add(config);
			}
		}
		if (null != company.getPgs()) {
			for (PropertyGroup pg : company.getPgs()) {
				companyPgIds.append(pg.getId());
				companyPgIds.append(',');
			}
		}
		modelAndView.addObject("configIds", builder.toString());
		modelAndView.addObject("configs", configDOs);
		modelAndView.addObject("pgIds", companyPgIds.toString());

		
		return modelAndView;
	}

	@RequestMapping(value = "/innov/updatecompany.do")
	public String updateCompany(@ModelAttribute("member") MemberDO member,
			@RequestParam("namecn") String namecn, String nameen,
			String description, String configs, HttpServletRequest request) {

		List<PropertyGroup> addPgs = getAddPgs(configs, request);
		// 添加对update的认证

		List<PropertyGroup> updatePgs = getUpdatePgs(request);

		int companyId = companyServices.updateCompany(member.getCompanyId(),
				namecn, nameen, description, updatePgs, addPgs);
		member.setcId(companyId);
		memberServices.updateMember(member);

		return "forward:/innov/company_info.do";
	}

	private List<PropertyGroup> getUpdatePgs(HttpServletRequest request) {
		List<PropertyGroup> updatePgs = new ArrayList<PropertyGroup>();
		@SuppressWarnings("unchecked")
		Enumeration<String> parameters = request.getParameterNames();
		Map<Integer, PropertyGroup> mapUpdatePgs = new HashMap<Integer, PropertyGroup>();
		while (parameters.hasMoreElements()) {
			String p = parameters.nextElement();
			if (p.startsWith("i_")) {
				String[] ps = p.split("_");

				if (ps.length != 3) {
					continue;
				}

				int gId = MyStringUtils.convertToInt(ps[1], 0);
				String gName = request.getParameter("p_value_" + gId);
				int parentId = MyStringUtils.convertToInt(
						request.getParameter("p_paranet_" + gId), 0);
				Item item = getItem(mapUpdatePgs, updatePgs, gId,
						MyStringUtils.convertToInt(ps[2], 0), gName, parentId);
				if (null == item) {
					continue;
				}
				String value = request.getParameter(p);
				item.setValue(value);
			} else if (p.startsWith("p_")) {
				String[] ps = p.split("_");
				if (ps.length != 4) {
					continue;
				}
				int gId = MyStringUtils.convertToInt(ps[1], 0);
				String gName = request.getParameter("p_value_" + gId);
				int parentId = MyStringUtils.convertToInt(
						request.getParameter("p_paranet_" + gId), 0);
				Item item = getItem(mapUpdatePgs, updatePgs,
						MyStringUtils.convertToInt(ps[1], 0),
						MyStringUtils.convertToInt(ps[2], 0), gName, parentId);
				int pId = MyStringUtils.convertToInt(ps[3], 0);
				if (0 == pId) {
					continue;
				}
				Pair pair = item.getProperty(pId);
				if (null == pair) {
					pair = new Pair();
					pair.setId(pId);
					item.addProperty(pair);
				}
				String value = request.getParameter(p);
				String name = request.getParameter(p + "_v");
				pair.setValue(value);
				pair.setKey(name);
			}

		}

		return updatePgs;
	}

	private Item getItem(Map<Integer, PropertyGroup> mapPgs,
			List<PropertyGroup> updatePgs, int pgId, int itemId, String gName,
			int parentId) {
		if (pgId == 0) {
			return null;
		}
		if (itemId == 0) {
			return null;
		}
		PropertyGroup pg = mapPgs.get(pgId);
		if (null == pg) {
			pg = new PropertyGroup();
			pg.setName(gName);
			pg.setId(pgId);
			pg.setParentId(parentId);
			mapPgs.put(pgId, pg);
			updatePgs.add(pg);
		}

		Item item = pg.getItem(itemId);
		if (null == item) {
			item = new Item();
			item.setId(itemId);
			item.setgId(pg.getId());
			item.setName(gName);
			pg.addItem(item);
		}
		return item;
	}

	private List<PropertyGroup> getAddPgs(String configs,
			HttpServletRequest request) {
		List<PropertyGroup> addPgs = new ArrayList<PropertyGroup>();
		Map<Integer, ConfigDO> mapConfigs = configServices
				.mapConfigsByType(ConfigTypeEnum.COMPANY_STANDARD_PROPERTIES);

		if (StringUtils.isNotBlank(configs)) {
			String[] configIds = configs.split(",");
			for (String configId : configIds) {
				if (StringUtils.isBlank(configId)) {
					continue;
				}
				ConfigDO configDO = mapConfigs.get(MyStringUtils.convertToInt(
						configId, 0));
				if (null == configDO) {
					continue;
				}
				String value = request.getParameter("config_" + configId);

				if (StringUtils.isNotBlank(value)) {
					PropertyGroup pg = new PropertyGroup(configDO.getId(), 0,
							configDO.getName(), value,
							configDO.getDescription(),
							PropertyGroupType.STANDARD, null);
					addPgs.add(pg);
				} else {
					if (null != configDO.getChildren()
							&& !configDO.getChildren().isEmpty()) {
						Map<String, String> properties = new HashMap<String, String>();
						for (ConfigDO child : configDO.getChildren()) {
							value = request.getParameter("config_" + configId
									+ "_" + child.getId());
							if (StringUtils.isNotBlank(value)) {
								properties.put(child.getName(), value);
							}
						}
						if (properties.size() > 0) {
							PropertyGroup pg = new PropertyGroup(
									configDO.getId(), 0, configDO.getName(),
									StringUtils.EMPTY,
									configDO.getDescription(),
									PropertyGroupType.STANDARD, properties);
							addPgs.add(pg);
						}
					}
				}
			}
		}
		return addPgs;
	}

	@ModelAttribute("member")
	public MemberDO getMember(HttpServletRequest request) {
		return securityManager.getMember(request);
	}

	public CompanyServices getCompanyServices() {
		return companyServices;
	}

	public void setCompanyServices(CompanyServices companyServices) {
		this.companyServices = companyServices;
	}

	public ConfigServices getConfigServices() {
		return configServices;
	}

	public void setConfigServices(ConfigServices configServices) {
		this.configServices = configServices;
	}

}
